#include "ipc/Cola.h"
#include <stdio.h>
#include <stdlib.h>
#include "log.h"

Cola::Cola(const char* path, int id){
    idCola = msgget(ftok(path, id), IPC_CREAT | 0666);
}

bool Cola::enviar(long idMensaje, const std::vector<char> &mensaje){
    mensaje_t aEnviar;
    int restante = mensaje.size();
    int inicio = 0;

    log("Tamanio del mensaje a enviar: %d, tamanio maximo: %d\n", mensaje.size(), MENSAJE_TAMANIO_MAX);
    log("idMensaje: %d\n", idMensaje);

    memset((void*)&aEnviar, 0, sizeof(aEnviar));

    aEnviar.id = idMensaje;
    aEnviar.cero = 0;
    while(restante > 0){
	int a_enviar=0;
	if(restante > MENSAJE_TAMANIO_MAX)
	    a_enviar = MENSAJE_TAMANIO_MAX;
	else
	    a_enviar = restante;

	memcpy(aEnviar.buffer,&mensaje[0]+inicio, a_enviar);
	aEnviar.mas_datos = (restante > a_enviar);
	aEnviar.tamanio = a_enviar;

	inicio += a_enviar;
	restante -= a_enviar;

	log("Mensaje.id: %ld, Mensaje.tamanio: %d, Tamanio total: %d\n", aEnviar.id, aEnviar.tamanio, sizeof(aEnviar));

	if(!msgsnd(idCola, &aEnviar, sizeof(mensaje_t), 0))
	    return false;
    }
    return true;
}

bool Cola::enviar(long idMensaje, const char* mensaje, unsigned tamanio){
    std::vector<char> datos;
    datos.insert(datos.begin(), mensaje, mensaje+tamanio);
    return enviar(idMensaje, datos);
}

bool Cola::recibir(long idMensaje, std::vector<char> &buffer, long &id_recibida){
    mensaje_t recibido;
    buffer.clear();

    do{
	if(msgrcv(idCola, &recibido, sizeof(mensaje_t), idMensaje, 0) == -1)
	    return false;

	buffer.insert(buffer.begin(), recibido.buffer, recibido.buffer+recibido.tamanio);
	id_recibida = recibido.id;
    }while(recibido.mas_datos);

    return true;
}

bool Cola::recibir(long idMensaje, std::vector<char> &buffer){
    long id_descartar;
    return recibir(idMensaje, buffer, id_descartar);
}


void Cola::destruir(const char* path, int id){
    int idCola = msgget(ftok(path, id), IPC_CREAT | 0666);
    msgctl(idCola, IPC_RMID, NULL);
}

Cola::~Cola(){
}
